home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
BARNET
/
FREENET
/
BRODIE
/
CAPTURET.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-05
|
4KB
|
176 lines
/* captureTCP.c */
/* (C) Copyright 1995, Stewart Brodie */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <ctype.h>
#include "sys/errno.h"
#include "netdb.h"
#include "netinet/in.h"
#include "sys/socket.h"
#include "sys/ioctl.h"
#include "sys/byteorder.h"
#include "sys/select.h"
static int s = -1,t = -1;
static void do_stop(void)
{
if (s > -1) { shutdown(s, 2); close(s); }
if (t > -1) { shutdown(t, 2); close(t); }
}
#define SYNTAX "captureTCP [-repeat] [<port|name> [capture file]]"
int main(int argc, char *argv[])
{
struct sockaddr_in sin;
struct hostent *he;
int port = 0, repeat = 0,size;
FILE *cap = NULL;
char cpbuf[BUFSIZ];
fd_set f;
fprintf(stderr, "captureTCP (C) Stewart Brodie (" __DATE__ ") vsn 0.01\n");
while (argc > 1) {
if (strcmp(argv[1], "-repeat")==0) repeat = 1;
else if (isdigit(*(argv[1]))) port = atoi(argv[1]);
else if (*(argv[1]) == '-') {
fprintf(stderr, "Syntax: " SYNTAX "\n");
return 1;
}
else {
if (port == 0) {
struct servent *se = getservbyname(argv[1],"tcp");
if (!se) {
fprintf(stderr, "service '%s' not known\n",
argv[1]);
return 1;
}
port = htons(se->s_port);
}
else if (!cap) {
cap = fopen(argv[1], "wb");
}
}
++argv; --argc;
}
if (!cap) cap = stdout;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) {
fprintf(stderr, "socket: %s\n", socket_errno_to_string());
return 1;
}
atexit(do_stop);
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
memset(sin.sin_zero, 0, 8);
if (bind(s, &sin, sizeof(sin)) == -1) {
fprintf(stderr, "bind: %s\n", socket_errno_to_string());
return 1;
}
if (listen(s, 5) == -1) {
fprintf(stderr, "listen: %s\n", socket_errno_to_string());
return 1;
}
size = 16;
if (getsockname(s, &sin, &size) == -1) {
fprintf(stderr, "bind: %s\n", socket_errno_to_string());
return 1;
}
port = htons(sin.sin_port);
fprintf(stderr, "Bound to port %d (%d,%d for FTP PORT)\n",
port, port / 256, port % 256);
fprintf(stderr, "Waiting for connection ...\n");
for (;;) {
struct timeval timeout;
int sr;
FD_ZERO(&f);
FD_SET(s, &f);
timerclear(&timeout);
sr = select(FD_SETSIZE, &f, NULL, NULL, &timeout);
if (sr == -1) {
if (errno == EWOULDBLOCK) {
continue;
}
else {
fprintf(stderr, "select: %s\n", socket_errno_to_string());
return 1;
}
}
if (sr == 0) {
continue;
}
size = 16;
t = accept(s, (struct sockaddr *)&sin, &size);
if (t == -1) {
fprintf(stderr, "accept: %s\n", socket_errno_to_string());
return 1;
}
break;
}
he = gethostbyaddr((void *)&sin.sin_addr.s_addr, 4, AF_INET);
if (!he) {
fprintf(stderr, "Connection from %s\n", inet_ntoa(sin.sin_addr));
}
else {
fprintf(stderr, "Connection from %s\n", he->h_name);
}
FD_ZERO(&f);
FD_SET(t, &f);
for (;;) {
fd_set f2 = f;
int in, sr;
struct timeval timeout;
timerclear(&timeout);
sr = select(FD_SETSIZE,&f2,NULL,NULL,&timeout);
if (sr == -1 && errno == EWOULDBLOCK) continue;
if (sr == 0) continue;
if (sr == -1) {
fprintf(stderr, "select: %s\n", socket_errno_to_string());
return 1;
}
in = recv(t, cpbuf, BUFSIZ, 0);
if (in == -1) {
fprintf(stderr, "recv: %s\n", socket_errno_to_string());
break;
}
if (in == 0) break;
if (in > 0) {
fwrite(cpbuf, 1, in, cap);
}
}
fclose(cap);
/* rely on atexit function to close sockets */
return 0;
}